package com.dx.service.impl;

import com.dx.context.ContextHolder;
import com.dx.converter.utils.InterfaceBoConverter.InterfaceBoConverter;
import com.dx.entity.bo.ParamsBo;
import com.dx.entity.dto.InterfaceBoDto;
import com.dx.exception.ThirdInterfaceException;
import com.dx.mapper.InterfaceMapper;
import com.dx.page.PageDomain;
import com.dx.utils.DynamicRequestService;
import com.dx.utils.JsonUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import com.dx.entity.bo.HeaderBo;
import com.dx.entity.bo.InterfaceBo;
import com.dx.entity.dto.InterfaceDto;
import com.dx.service.InterfaceOpService;
import com.github.pagehelper.PageHelper;
import com.dx.entity.dto.InterfaceQueryDto;


import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;

/**
 * 1.xml文件要放在resources/mapper下
 * 且在application.yaml中配置
 * 不然会报unabled to bound method error
 *
 * 2.查询条件要判断是否是null，concat('%','null','concat')结果为null
 *
 */



@Service
@RequiredArgsConstructor
public class interfaceOpServiceImpl implements InterfaceOpService {
    //TODO 后续根据实际登陆用户获取创建者id
    private  Long currentUserId = 1L;
    private final InterfaceMapper interfaceMapper;
    private final DynamicRequestService dynamicRequestService;

    @Override
    public InterfaceDto getInterface(Long id) {
        InterfaceDto interfaceDto = new InterfaceDto();
        InterfaceBo interfaceBo=interfaceMapper.getInterface(id);
        List<ParamsBo> paramsBos=interfaceMapper.getInterfaceParamsByInterfaceId(id);
        List<HeaderBo> headerBos=interfaceMapper.getInterfaceHeadersByInterfaceId(id);
        //把paramsBos转化为一个map，key为name，value为value
        HashMap<String, String> params = new HashMap<>();
        for (ParamsBo paramsBo : paramsBos) {
            params.put(paramsBo.getName(), paramsBo.getDefaultValue());
        }
        //把headerBos转化为一个map，key为name，value为value
        HashMap<String, String> headers = new HashMap<>();
        for (HeaderBo headerBo : headerBos) {
            headers.put(headerBo.getName(), headerBo.getDefaultValue());
        }
        InterfaceBoDto interfaceBoDto = new InterfaceBoDto();
        BeanUtils.copyProperties(interfaceBo, interfaceBoDto);
        interfaceBoDto.setRequestBody(JsonUtils.toHashMap(interfaceBo.getRequestBody()));
        interfaceDto.setInterfaceBoDto(interfaceBoDto);





//        interfaceBoDto.setRequestBody();
//        interfaceDto.setInterfaceBo(interfaceBo);
        interfaceDto.setParams(params);
        interfaceDto.setHeaders(headers);
        return interfaceDto;

    }

    @Override
    public void insertInterface(InterfaceDto interfaceDto) {
        final InterfaceBoDto interfaceBoDto = interfaceDto.getInterfaceBoDto();
        InterfaceBo interfaceBo = new InterfaceBo();
        BeanUtils.copyProperties(interfaceBoDto, interfaceBo);
        interfaceBo.setRequestBody(JsonUtils.toJson(interfaceBoDto.getRequestBody()));

        //当前用户id
        currentUserId= ContextHolder.getUser().getId();
        interfaceBo.setCreatedBy(currentUserId);
        interfaceBo.setUpdatedBy(currentUserId);
        interfaceBo.setCreatedTime(LocalDateTime.now());
        interfaceBo.setUpdatedTime(LocalDateTime.now());

        interfaceMapper.insertInterface(interfaceBo, interfaceBo.getRequestBody());
        Long interfaceId=interfaceBo.getId();


//        interfaceMapper.insertInterface(interfaceDto.getInterfaceBo(),interfaceDto.getHashRequestBodyBo().toString());
//        System.out.println("interfaceDto.getHashRequestBodyBo().toString() = " + interfaceDto.getHashRequestBodyBo().toString());
//        Long interfaceId=interfaceDto.getInterfaceBo().getId();

        System.out.println(interfaceId);
        for (String name : interfaceDto.getParams().keySet()) {
            System.out.println("interfaceId = " + interfaceId);
            interfaceMapper.insertInterfaceParams(interfaceId, name, interfaceDto.getParams().get(name));
        }
        for (String name : interfaceDto.getHeaders().keySet()) {
            interfaceMapper.insertInterfaceHeaders(interfaceId, name, interfaceDto.getHeaders().get(name));
        }
    }

    @Override
    public void deleteInterface(Long interfaceId) {
        //删除关联的参数
        interfaceMapper.deleteInterfaceParamsByInterfaceId(interfaceId);
        //删除关联的头
        interfaceMapper.deleteInterfaceHeadersByInterfaceId(interfaceId);
        //删除接口
        interfaceMapper.deleteInterface(interfaceId);
    }

    /**
     * 更新接口
     * @param interfaceDto
     */


    @Override
    public void updateInterface(InterfaceDto interfaceDto) {
        InterfaceBo interfaceBo = InterfaceBoConverter.convertToBo(interfaceDto.getInterfaceBoDto());
        currentUserId=ContextHolder.getUser().getId();
        interfaceBo.setUpdatedBy(currentUserId);
        interfaceBo.setUpdatedTime(LocalDateTime.now());

        interfaceMapper.updateInterface(interfaceBo);
        Long interfaceId=interfaceDto.getInterfaceBoDto().getId();
        interfaceMapper.deleteInterfaceParamsByInterfaceId(interfaceId);
        interfaceMapper.deleteInterfaceHeadersByInterfaceId(interfaceId);
        for (String name : interfaceDto.getParams().keySet()) {
            interfaceMapper.insertInterfaceParams(interfaceId, name, interfaceDto.getParams().get(name));
        }
        for (String name : interfaceDto.getHeaders().keySet()) {
            interfaceMapper.insertInterfaceHeaders(interfaceId, name, interfaceDto.getHeaders().get(name));
        }
    }



    @Override
    public Object executeInterface(Long id) {
        final InterfaceDto anInterface = getInterface(id);
        final String url = anInterface.getInterfaceBoDto().getUrl();
        final String requestBody = JsonUtils.toJson(anInterface.getInterfaceBoDto().getRequestBody());
        final HashMap<String, String> params = anInterface.getParams();
        final HashMap<String, String> headers = anInterface.getHeaders();
        final String method = anInterface.getInterfaceBoDto().getMethod();


        //根据上述发送http请求到目标接口
        ResponseEntity<String> stringResponseEntity = null;
        String responseBody=null;
        Object result = null;
        HashMap resultMap=null;
        int maxRetries = 3;
        for (int i = 0; i < maxRetries; i++) {
            //第i次调用
            System.out.println("第" + (i + 1) + "次调用");
            //String method转化为HttpMethod
            HttpMethod httpmethod = HttpMethod.valueOf(method);
            stringResponseEntity = dynamicRequestService.sendDynamicRequest(url, httpmethod, headers, params, requestBody);
            responseBody = stringResponseEntity.getBody();
            System.out.println("响应体" + responseBody);
            try{
                resultMap = JsonUtils.toObject(responseBody, HashMap.class);
            }catch (Exception e){
                result=JsonUtils.toObject(responseBody, Object.class);
            }

            if (stringResponseEntity.getStatusCode() == HttpStatus.OK) {
//                return responseBody;
                if (resultMap==null) {
                    return result;
                }else{
                    return resultMap;
                }

            }
        }
        if (stringResponseEntity.getStatusCode() == HttpStatus.OK) {
            if (resultMap==null) {
                return result;
            }else{
                return resultMap;
            }
        }else{
            throw new ThirdInterfaceException("请求失败");
        }
            //把json字符串转变为R<?>对象
//            result = JsonUtils.toObject(responseBody, R.class);
//            System.out.println("响应体" + result);
//
//            if (result.getCode() != R.FAIL) {
//                break;
//            }
//        }
//        if (result.getCode() == R.FAIL) {
//            throw new RuntimeException("请求失败");
//        }



    }

    /*
    使用pagehelper分页查询
    如果没有maven导入依赖库
    可能就没有import提示
     */
    @Override
    public List<InterfaceBo> list(InterfaceQueryDto interfaceQueryDto) {
        PageDomain pageDomain = interfaceQueryDto.getPageDomain();
        PageHelper.startPage(pageDomain.getPageNum(), pageDomain.getPageSize(), pageDomain.getOrderBy());
//        System.out.println("interfaceBoDto" + interfaceDto.getInterfaceBoDto());
//        System.out.println("interfaceDto = " + interfaceDto.getInterfaceBoDto().getName());
//        System.out.println("interfaceDto = " + interfaceDto.getInterfaceBoDto().getDescription());
//        System.out.println("interfaceDto = " + interfaceDto.getInterfaceBoDto().getUrl());
//        System.out.println("interfaceDto = " + interfaceDto.getInterfaceBoDto().getMethod());
        InterfaceBo interfaceBo = InterfaceBoConverter.convertToBo(interfaceQueryDto.getInterfaceBoDto());
        List<InterfaceBo> interfaceBos = interfaceMapper.list(interfaceBo);
        System.out.println("interfaceBos = " + interfaceBos);
        interfaceBos.forEach(iBo -> {
            System.out.println("interfaceBo.getName() = " + iBo.getName());
        });
        return interfaceBos;
//        return interfaceBos.stream().map(interfaceBo -> {
//        }).collect(Collectors.toList());
//        return interfaceBos.stream().map(interfaceBo -> InterfaceBoConverter.convertToDto(interfaceBo)).collect(Collectors.toList());
    }


}
